#include <iostream>
#include <string>
#include "imDB.h"
#include <jsoncpp/json/json.h>
#include <stdio.h>
#include <stdlib.h>
#include <wsim/websocket_server.h>
#include "wsim_server.h"
#include "myconfig.h"

using namespace std;

#define TTY_PATH    "/dev/tty"
#define STTY_CLOSE  "stty raw -echo -F"
#define STTY_OPEN   "stty -raw echo -F"

imDB db;
void printUserList()
{
	Json::Value usersJson;
	int ret=db.getUserArry(usersJson);
	if(ret>0)
	{
            Json::Value fields=usersJson["fields"];
            for(int f=0;f<fields.size();++f)
            {
                cout<<fields[f]["name"].asString()<<"\t";
            }
            cout<<endl;
            Json::Value rows=usersJson["rows"];
            for(int r=0;r<rows.size();++r)
            {
                Json::Value row=rows[r];
                for(int f=0;f<fields.size();++f)
                {
                    string name=fields[f]["name"].asString();
                    cout<<row[name]<<"\t";
                }
                cout<<endl;
            }
            cout<<endl;
            //cout<<usersJson.toStyledString()<<endl;
            /*	int rSize=usersJson.size();
		for(int i=0;i<rSize;++i)
		{
			int cSize=usersJson[i].size();
			for(int j=0;j<cSize;++j)
			{
				cout<<"\t"<<usersJson[i][j];
			}
			cout<<endl;
                }*/
	}
}
void printHelp()
{
    //cout<<"\twsimctl user \t\t\t显示注册用户"<<endl;
    cout<<"\twsimctl user print\t\t\t显示注册用户"<<endl;
    cout<<"\twsimctl user add\t\t\t添加用户"<<endl;
    cout<<"\twsimctl user verified <昵称>\t\t核准用户"<<endl;
    cout<<"\twsimctl user prohibit <昵称>\t\t禁止用户"<<endl;
    cout<<"\twsimctl user delete <昵称>\t\t删除用户"<<endl;
    cout<<"\twsimctl organ print\t\t\t显示机构列表"<<endl;
    cout<<"\twsimctl client status\t\t\t显示客户状态"<<endl;
    cout<<"\twsimctl creat dbcfg\t\t\t配置数据库连接"<<endl;
    cout<<"\twsimctl creat table\t\t\t创建数据表"<<endl;
}
void organprint()
{
	Json::Value organJson;
	int ret=db.getOrganArry(organJson);
	if(ret>0)
	{
            Json::Value fields=organJson["fields"];
            for(int f=0;f<fields.size();++f)
            {
                cout<<fields[f]["name"].asString()<<"\t";
            }
            cout<<endl;
            Json::Value rows=organJson["rows"];
            for(int r=0;r<rows.size();++r)
            {
                Json::Value row=rows[r];
                for(int f=0;f<fields.size();++f)
                {
                    string name=fields[f]["name"].asString();
                    cout<<row[name]<<"\t";
                }
                cout<<endl;
            }
            cout<<endl;

	}
}
void addUser()
{
beginadd:
    cout<<endl<<"创建新用户"<<endl<<"昵称（登录名）：";
    string nickname;
    cin>>nickname;
    cout<<"密码：";
    string pwd;
    system(STTY_CLOSE TTY_PATH);
    cin>>pwd;
    system(STTY_OPEN TTY_PATH);
    if(nickname.length()==0)
    {
        cout<<"昵称不能为空！"<<endl;
        goto beginadd;
    }
    if(pwd.length()<6)
    {
        cout<<"密码不能小于6位！"<<endl;
        goto beginadd;
    }
    if(!db.regName(nickname,pwd))
    {        
        cout<<"用户\""<<nickname<<"\"添加失败!!!"<<endl;
        return ;
    }
    cout<<endl<<"所属机构：";    
    string organ;
    cin>>organ;
    db.reOrgan(nickname,organ);
    cout<<"姓名：";
    string name;
    cin>>name;
    db.reName(nickname,name);
    cout<<"手机号：";
    string mobnum;
    cin>>mobnum;
    db.reMobileNumber(nickname,mobnum);
    db.reVerified(nickname,true);
    cout<<"用户\""<<nickname<<"\"添加成功。"<<endl;
}

int shm_clients(void) {
    key_t key;
    int shmid, semid, msqid;
    char *shm;
    struct msg_form msg;
    int flag = 1; /*while循环条件*/

    // 获取key值
    if((key = ftok(".", 'x')) < 0)
    {
        perror("ftok error");
        exit(1);
    }

    // 获取共享内存
    if((shmid = shmget(key, WSCLIENTIPC_SIZE, 0)) == -1)
    {
        perror("shmget error");
        exit(1);
    }

    // 连接共享内存
    shm = (char*)shmat(shmid, 0, 0);
    if((int)shm == -1)
    {
        perror("Attach Shared Memory Error");
        exit(1);
    }

    // 创建消息队列
    if ((msqid = msgget(key, 0)) == -1)
    {
        perror("msgget error");
        exit(1);
    }

    // 获取信号量
    if((semid = semget(key, 0, 0)) == -1)
    {
        perror("semget error");
        exit(1);
    }
// 读数据
    CLEAR();//清屏
    MOVETO(3,0);//定位光标    
    printf("fd\t\tstatus\t\treged\t\tbufLen\t\tnickname\t\torgan\t\tgroup\n");   
    HIDE_CURSOR();
    pid_t pid;
    if((pid = fork()) == -1)
        perror("Fork Error");
    else if(pid == 0) /*子进程*/
    {
        while(1)
        {
        char c;        
        //scanf("%c", &c);
        c=getchar();
        if (c=='q')
        {            
            
                msg.mtype = 9754;
                msg.mtext = 'q';
                msgsnd(msqid, &msg, sizeof(msg.mtext), 0);
                
                break;
           }
           else{         
                /*清空标准输入缓冲区*/
                while((c=getchar())!='\n' && c!=EOF);
            }
        }
    }
    else  /*父进程*/
    {
    while(1)
    {
        msgrcv(msqid, &msg, 1, 9754, 0); /*读取类型为9753的消息*/
        if(msg.mtext == 'q')  /*quit - 跳出循环*/
            break;        
        else if(msg.mtext == 'c')  /*read - 读共享内存*/
        {
             
            sem_p(semid);            
            WSCLIENT_IPC* pdata=(WSCLIENT_IPC*)shm;
            MOVETO(pdata->fd,0);//定位光标
            ROWCLEAR();
            if(strcmp(pdata->status,"closeed")==0)
            printf("\033[40;31m");
            else if(strcmp(pdata->status,"forward")==0)
            printf("\033[40;32m");
            else if(strcmp(pdata->status,"accept")==0)
            printf("\033[40;33m");
            else printf("\033[40;37m");
            printf("%d\t\t%s\t\t%d\t\t%d\t\t%s\t\t%s\t\t%s\n",pdata->fd,pdata->status,pdata->breg,pdata->bufLen,pdata->nickname,pdata->organ,pdata->group);
            sem_v(semid);
        }
    }
    }
    // 断开连接
    shmdt(shm);

    return 0;
}
void dbcfg()
{
    mycfg* pcfg=new mycfg(CFGFILE);
    cout<<"DBSERVER=";
    string sDBSERVER;
    cin>>sDBSERVER;
    pcfg->setValue("DBSERVER",sDBSERVER);
    cout<<"DBUSER=";
    string sDBUSER;
    cin>>sDBUSER;
    pcfg->setValue("DBUSER",sDBUSER);
    cout<<"DBPASSWORD=";
    string sDBPASSWORD;
    cin>>sDBPASSWORD;
    pcfg->setValue("DBPASSWORD",sDBPASSWORD);
    cout<<"DBSPACE=";
    string sDBSPACE;
    cin>>sDBSPACE;
    pcfg->setValue("DBSPACE",sDBSPACE);
    pcfg->WriteConfig();
    cout<<"请重启服务..."<<endl;
}
void creattable()
{
    db.creatJoinTable();
    cout<<"操作完成，请重启服务..."<<endl;
}
int main(int argc,char *argv[])
{
   mycfg* pcfg=new mycfg(CFGFILE);
    
    std::string value;    
    value=pcfg->getValue( "DBSERVER");
    string strIP=DBSERVER;
    if(value.size()>0)
        strIP=value;
    value.resize(0);
    value=pcfg->getValue("DBUSER");
    string strUser=DBUSER;
    if(value.size()>0) strUser=value;
    value.resize(0);
    value=pcfg->getValue( "DBPASSWORD");
    string strPwd=DBPASSWORD;
    if(value.size()>0)
        strPwd=value;
    value.resize(0);
    value=pcfg->getValue("DBSPACE");
    string strSpace=DBSPACE;
    if(value.size()>0) strSpace=value;
    db.reInitDB(strIP,strUser,strPwd,strSpace);

	if(argc<2)
	{
            printHelp();
	}
	else{
		string cmd1=argv[1];
		if(cmd1.compare(0,4,"user")==0)
		{
                    if(argc>=3)
                    {
                        string cmd2=argv[2];
                        if(cmd2.compare(0,5,"print")==0) printUserList();
                        else if(cmd2.compare(0,3,"add")==0) addUser();
                        else if(cmd2.compare(0,6,"delete")==0)
                        {
                            if(argc==4)
                            {
                                string nickname=argv[3];
                                db.delNickname(nickname);
                                cout<<"操作完成。"<<endl;
                            }
                            else
                                printHelp();
                        }
                        else  if(cmd2.compare(0,8,"verified")==0)
                        {
                            if(argc==4)
                            {
                                string nickname=argv[3];
                                db.reVerified(nickname,true);
                                cout<<"操作完成。"<<endl;
                            }
                            else
                                printHelp();
                        }
                        else  if(cmd2.compare(0,8,"prohibit")==0)
                        {
                            if(argc==4)
                            {
                                string nickname=argv[3];
                                db.reVerified(nickname,false);
                                cout<<"操作完成。"<<endl;
                            }
                            else
                                printHelp();
                        }
                        else
                            printHelp();
                    }

		}
        else if(cmd1.compare(0,6,"client")==0){
                if(argc>=3)
                    {
                        string cmd2=argv[2];
                        if(cmd2.compare(0,6,"status")==0) shm_clients();
                        else
                        {
                            printHelp();
                        }
                    }
                    else
                    {
                        printHelp();
                    }
                      
        }
        else if(cmd1.compare(0,5,"organ")==0){
            if(argc>=3)
            {
                string cmd2=argv[2];
                if(cmd2.compare(0,5,"print")==0) organprint();
                else printHelp();
            }
            else printHelp();
        }
        else if(cmd1.compare(0,5,"creat")==0){
            if(argc>=3)
            {
                string cmd2=argv[2];
                if(cmd2.compare(0,5,"dbcfg")==0) dbcfg();
                else if(cmd2.compare(0,5,"table")==0) creattable();
                else printHelp();
            }
            else printHelp();
        }
                else
                    printHelp();
	}
	return 1;
}
